package com.itlong.cloud.network.tcp.netty;

import com.itlong.cloud.POJO.DTO.common.ParkingMessageDTO;
import com.itlong.cloud.enumerate.ParkingBusinessOrderEnum;
import com.itlong.cloud.network.tcp.SpringContextUtils;
import com.itlong.cloud.service.IParkingPassRecordService;
import com.itlong.cloud.utils.node.JsonUtil;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.socket.SocketChannel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * <desc>
 * 通道消息处理类。
 * </desc>
 *
 * @createDate 2018/11/6
 */
public class ServerStringHandler extends ChannelInboundHandlerAdapter {


    private static final Logger LOG = LoggerFactory.getLogger(ServerStringHandler.class);

    IParkingPassRecordService iParkingPassRecordService = (IParkingPassRecordService) SpringContextUtils.getBean("iParkingPassRecordService");
    private CountDownLatch latch;

    //消息唯一ID
    private String unidId = "";

    //消息同步标志
    private int rec;

    //客户端返回的数据
    private ParkingMessageDTO parkingMessageDTO;


    /**
     * <desc>
     *      客户端连接进来的事件
     * </desc>
     *
     * @param ctx 服务通道处理
     * @author Wenchao.L
     * @createDate 2018/11/1
     */
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
//        LOG.info("有新客户端连接接入。。。" + ctx.channel().remoteAddress());
    }


    /**
     * <desc>
     *      通道上注册的读写事件
     * </desc>
     *
     * @param ctx 服务通道处理
     * @param msg 数据
     * @author Wenchao.L
     * @createDate 2018/11/1
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
        //LOG.info(msg);
        if (msg != null) {
            ParkingMessageDTO message = JsonUtil.toObject(msg.toString(), ParkingMessageDTO.class);
            //心跳信息
            if (message.getType() == ParkingBusinessOrderEnum.PING.getType()) {

                ParkingMessageDTO rm = new ParkingMessageDTO();
                rm.setType(ParkingBusinessOrderEnum.PING.getType());
                rm.setContent("pong");
                String mets = JsonUtil.toJSON(rm);
                //ctx.writeAndFlush(Unpooled.copiedBuffer(("").getByte("UTF-8")));
                ctx.writeAndFlush(Unpooled.copiedBuffer((mets + "\001").getBytes()));
            }
            //判断是否是初始化信息，如果是就将客户端信息初始化到全局map中
            if (message.getType() == ParkingBusinessOrderEnum.INIT_DATA.getType()) {
                ChannelPoolManage.add(message.getId(), (SocketChannel) ctx.channel());
                ChannelPoolManage.setChannelLock(message.getId(), new ReentrantReadWriteLock().writeLock());
            }

            //从客户端传来的入场记录
            if (message.getType() == ParkingBusinessOrderEnum.QUERY_PARKING_FEE.getType()
                    || message.getType() == ParkingBusinessOrderEnum.PAY_MONTHLY_CARD.getType()
                    || message.getType() == ParkingBusinessOrderEnum.PAY_FEE.getType()){
                //校验返回的信息是否是同一个信息
                if (unidId.equals(message.getMessageId())) {
                    latch.countDown();//消息返回完毕，释放同步锁，具体业务需要判断指令是否匹配
                    rec = 0;
                    parkingMessageDTO = message;
                }
            }else if (message.getType() == ParkingBusinessOrderEnum.QUERY_IN_RECORD.getType()) {
                //这里调用serivce保存入场记录
                iParkingPassRecordService.addInPassRecord(message.getId(),message.getContent());
            }else if (message.getType() == ParkingBusinessOrderEnum.QUERY_OUT_RECORD.getType()) {
                //这里调用serivce保存出场记录
                iParkingPassRecordService.addOutPassRecord(message.getId(),message.getContent());
            }
        }
    }


    /**
     * <desc>
     *      发生服务器连接发生异常事件
     * </desc>
     *
     * @param ctx   服务通道处理
     * @param cause 异常
     * @author Wenchao.L
     * @createDate 2018/11/1
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        cause.printStackTrace();
        ctx.close();
    }


    /**
     * <desc>
     *      当服务关闭清空全局Map的连接
     * </desc>
     *
     * @param ctx 服务通道处理
     * @author Wenchao.L
     * @createDate 2018/11/1
     */
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        //channel失效，从Map中移除
        ChannelPoolManage.remove((SocketChannel) ctx.channel());
    }


    public void resetSync(CountDownLatch latch, int rec) {
        this.latch = latch;
        this.rec = rec;
    }

    public void setUnidId(String unidId) {
        this.unidId = unidId;
    }
    public ParkingMessageDTO getParkingMessageDTO() {
        return parkingMessageDTO;
    }

}
